<?php

class Address {
	public $id_adresa; 			//id-ul adresi in tabel
	public $tip; 				//0 - Client; 1 - Firma; 2 - Comanda
	public $id_owner; 			//clientul / firma / comanda care are adresa this->
	public $adresa;
	public $oras;
	public $judet;
	public $cod_postal;
	public $tara;
	public $nume_firma;			//Doar pt tipul 2 (firma de la adresa x); in rest NULL = default value
    public $tip_loc;            //0 - incarcare; 1 - descarcare; 2 - vama import; 3 - vama export
	public $impexp;				//Doar pt tipul 2, tip loc 2 si 3 - numele firmei importatoare / exportatoare
	public $version;			//Numarul de modificari
	public $status;				//0 - Unmodified; 1 - Modified; 2 - New; 3 - Deleted;
    public $data;               // data incarcarii/descarcarii
    public $data_efectiva;      // data efectuarii efective a incarcarii/descarcarii
    public $nume_contact;       // nume contact incarcare/descarcare
    public $tel_contact;        // telefon contact incarcare/descarcare
    public $tip_marfa;          // tip marfa
    public $nr_colete;          // numar de colete
    public $greutate;           // greutatea incarcaturii
    public $alte_mentiuni;      // alte mentiuni
    public $legatura_incarcare; // alte mentiuni
    public $nume_birou_vamal;   // nume birou vamal
    public $cod_vama;           //cod vamal
    
	public function __construct($tip, $adresa, $oras, $judet, $cod_postal, $tara, $nume_firma = null, $tip_loc = null) {
		$this->id_adresa = CT_NOT_SAVED_YET;
	    $this->tip = (int) $tip;
		$this->id_owner = CT_NOT_SAVED_YET; 			
		$this->adresa = $adresa;
		$this->oras = $oras;
		$this->judet = $judet;
		$this->cod_postal = $cod_postal;
		$this->tara = $tara;
		$this->nume_firma = $nume_firma;
		$this->tip_loc = (int) $tip_loc; 		// needs cast?????
		$this->version = 0; 					//default value
		$this->status = CT_ADDRESS_NEW;			//a NEW address
        $this->data = date('Y-m-d H:00');
	}	
	
	public function queryInsertAddress($db) {
		
		$query = $db->prepare("INSERT INTO `adresa`  ( 	`tip` , 			`id_owner` , 
														`adresa` , 			`oras`,
	                        		        			`judet` ,    		`cod_postal` , 
		                        	        			`tara` , 		    `nume_firma` , 
		                                				`tip_loc` ,			`version`,
                                                        `impexp`,           `data`,
                                                        `data_efectiva`,    `nume_contact`,
                                                        `tel_contact`,      `tip_marfa`,
                                                        `nr_colete`,        `greutate`,
                                                        `alte_mentiuni`,    `nume_birou_vamal`,
                                                        `cod_vama`,         `legatura_incarcare`
		                               				) 
            								VALUES  (	:tip,       :id_owner, 
		            									:adresa,   	:oras, 
		                      							:judet,    	:cod_postal, 
		                      							:tara,     	:nume_firma,
		                      							:tip_loc,   :version,
                                                        :impexp,    :data,
                                                        :data_efectiva,    :nume_contact,
                                                        :tel_contact,      :tip_marfa,
                                                        :nr_colete,        :greutate,
                                                        :alte_mentiuni,    :nume_birou_vamal,
                                                        :cod_vama,         :legatura_incarcare
		                      						)");
		
		
		$query->bindParam(':tip', 			($this->tip));
		$query->bindParam(':id_owner', 		($this->id_owner));
		$query->bindParam(':adresa', 		($this->adresa));
		$query->bindParam(':oras', 			($this->oras));
		$query->bindParam(':judet', 		($this->judet));
		$query->bindParam(':cod_postal',	($this->cod_postal));
		$query->bindParam(':tara', 			($this->tara));
		$query->bindParam(':nume_firma', 	($this->nume_firma));
        $query->bindParam(':tip_loc',       ($this->tip_loc));
		$query->bindParam(':impexp', 		($this->impexp));
        $query->bindParam(':version',       ($this->version));
        $query->bindParam(':data',          ($this->data));
        $query->bindParam(':data_efectiva', ($this->data_efectiva));
        $query->bindParam(':nume_contact',  ($this->nume_contact));
        $query->bindParam(':tel_contact',   ($this->tel_contact));
        $query->bindParam(':tip_marfa',     ($this->tip_marfa));
        $query->bindParam(':nr_colete',     ($this->nr_colete));
        $query->bindParam(':greutate',      ($this->greutate));
        $query->bindParam(':alte_mentiuni', ($this->alte_mentiuni));
        $query->bindParam(':nume_birou_vamal',         ($this->nume_birou_vamal));
        $query->bindParam(':cod_vama',         ($this->cod_vama));
		$query->bindParam(':legatura_incarcare', 		($this->legatura_incarcare));
        
		if ($query->execute() === FALSE) {			
            $errInfo = $query->errorInfo();

            $errInfo = $errInfo[2];
	  		$query->closeCursor();	  		
			throw new QueryInsertAddressException("Failed saving address to the database" . $errInfo);
		}
	  			  		
  		$this->id_adresa = (int) $db->lastInsertId();
  			  	
	  	$query->closeCursor();
	  	
		return $this->id_adresa; 		//return the user id
	}
    
	public function queryUpdateAddress($db) {		
	    $this->version++;
		$query = $db->prepare("UPDATE `adresa` SET      `tip` = :tip , 			
														`adresa` = :adresa, 	`oras` = :oras,
	                        		        			`judet` = :judet,    	`cod_postal` = :cod_postal, 
		                        	        			`tara` = :tara, 		`nume_firma` = :nume_firma, 
		                                				`tip_loc` = :tip_loc,   `version` = :version,
                                                        `impexp` = :impexp,     `data` = :data,
                                                        `data_efectiva` = :data_efectiva,     `nume_contact` = :nume_contact,
                                                        `tel_contact` = :tel_contact,     `tip_marfa` = :tip_marfa,
                                                        `nr_colete` = :nr_colete,     `greutate` = :greutate,
                                                        `alte_mentiuni` = :alte_mentiuni,     `nume_birou_vamal` = :nume_birou_vamal,
                                                        `cod_vama` = :cod_vama,         `legatura_incarcare` = :legatura_incarcare
                				WHERE version < :version 
                				AND id = :id
               	  				AND id_owner = :id_owner");					                                						                                						                                				

		$query->bindParam(':tip', 			($this->tip));
		$query->bindParam(':adresa', 		($this->adresa));
		$query->bindParam(':oras', 			($this->oras));
		$query->bindParam(':judet', 		($this->judet));
		$query->bindParam(':cod_postal', 	($this->cod_postal));
		$query->bindParam(':tara', 			($this->tara));
		$query->bindParam(':nume_firma', 	($this->nume_firma));
        $query->bindParam(':tip_loc',       ($this->tip_loc));
		$query->bindParam(':impexp', 		($this->impexp));
		$query->bindParam(':version', 		($this->version));
		$query->bindParam(':id', 			($this->id_adresa));
        $query->bindParam(':id_owner',         ($this->id_owner));
        $query->bindParam(':data',         ($this->data));
        $query->bindParam(':data_efectiva',         ($this->data_efectiva));
        $query->bindParam(':nume_contact',         ($this->nume_contact));
        $query->bindParam(':tel_contact',         ($this->tel_contact));
        $query->bindParam(':tip_marfa',         ($this->tip_marfa));
        $query->bindParam(':nr_colete',         ($this->nr_colete));
        $query->bindParam(':greutate',         ($this->greutate));
        $query->bindParam(':alte_mentiuni',         ($this->alte_mentiuni));
        $query->bindParam(':nume_birou_vamal',         ($this->nume_birou_vamal));
        $query->bindParam(':cod_vama',         ($this->cod_vama));
		$query->bindParam(':legatura_incarcare', 		($this->legatura_incarcare));

		if ($query->execute() === FALSE) {	

            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
			$this->version--;
	  		$query->closeCursor();
	  		throw new QueryUpdateAddressException("Failed updating address - owner's id: " . $this->id_owner . $errInfo);
		}
			    	       
	    if ($query->rowCount() == 0) { 
	    	$this->version--;
			$query->closeCursor();
	       	throw new QueryWrongVersionException("Failed updating address. Reason: wrong version!");
	    }
	    
	    //close the cursor
  		$query->closeCursor();
	    	    
	    //reset the status to unmodified for a possible re-edit;
	    $this->status = CT_ADDRESS_UNMODIFIED;  
        return CT_RESULT_OK;
	}
	
  	public static function queryLoadAddress($db, $id_adresa) {
        $query = $db->prepare("SELECT *
                    			FROM adresa
                    			WHERE id = :id_adresa");
        
        $query->bindParam(':id_adresa', $id_adresa);
        
        if ($query->execute() === FALSE) {
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
	  		$query->closeCursor();
        	throw new QueryLoadAddressException("Failed loading address with id: " . $id_adresa . $errInfo);
        }
                        
        $data = $query->fetch(PDO::FETCH_ASSOC);        
        
        $address = new Address($data['tip'], $data['adresa']
                            , $data['oras'], $data['judet'], $data['cod_postal'], $data['tara'], $data['nume_firma'], $data['tip_loc']);
                            
        $address->id_adresa = (int) $data['id'];
        $address->id_owner = (int) $data['id_owner'];
        $address->version = $data['version'];
        $address->impexp = $data['impexp'];
        $address->data = $data['data'];
        $address->data_efectiva = $data['data_efectiva'];
        $address->nume_contact = $data['nume_contact'];
        $address->tel_contact = $data['tel_contact'];
        $address->tip_marfa = $data['tip_marfa'];
        $address->nr_colete = $data['nr_colete'];
        $address->greutate = $data['greutate'];
        $address->alte_mentiuni = $data['alte_mentiuni'];
        $address->nume_birou_vamal = $data['nume_birou_vamal'];
        $address->cod_vama = $data['cod_vama'];
        $address->legatura_incarcare = $data['legatura_incarcare'];
        
        $address->status = 0;	//the default value: UNMODIFIED
        $query->closeCursor();
        return $address;
    }
    
    //deletes the address that the object points to...
    //TODO: we need to destroy the object after this method is called???? OR
    //IDEA: we could use the object's attributes as a back-up for an UNDO option... simply recall queryInsertAddress
    
    function queryDeleteAddress($db) {
      	$query = $db->prepare("DELETE FROM adresa WHERE id = :id_adresa");
      	
      	$query->bindParam(':id_adresa', $this->id_adresa);     
      	if ($query->execute() === FALSE) {
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
	  		$query->closeCursor();
	  		throw new QueryDeleteAddressException("Failed deleting address with id: " . $this->id_adresa . $errInfo);
      	}  
      	                                  
  		$query->closeCursor();    		
    	
  		return CT_RESULT_OK;      	
    }
    
    //deletes an address by id; does not require an object.... STATIC
    public static function deleteAddressById($db, $id_adresa) {
    	$query = $db->prepare("DELETE FROM adresa WHERE id = :id_adresa");
    	
    	$query->bindParam(':id_adresa', $id_adresa);
    	    	
      	if ($query->execute() === FALSE) {      		
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
	  		$query->closeCursor();
    	  	throw new QueryDeleteAddressException("Failed deleting address by id (static) with id: " . $id_adresa . $errInfo);
      	}
    	  	
      	$query->closeCursor();
      	return CT_RESULT_OK;
    }
    
    /*
     * metoda ce se foloseste la statistici, pentru campurile de tara incarcare/descarcare
     * @author Flavius
     * @param databaseconection_link $db
     * @param int $id_client
     * @return un array de tari ale comenzilor 
     */
    
    public static function queryLoadCountriesByClientForCommands($db, $id_client) {
		
    	$query = $db->prepare("SELECT tara FROM `adresa`
                  				WHERE 
                  					id_owner = :id_client
                    				AND tip = " . CT_ADRESA_COMANDA . "                    				
                    				AND (
                    					tip_loc = " . CT_ADRESA_COMANDA_INCARCARE . "
                    					OR 
                    					tip_loc = " . CT_ADRESA_COMANDA_DESCARCARE . "
                    				)
                    			GROUP BY tara
                  				LIMIT 1");
        
        $query->bindParam(':id_client', $id_client);
                
        if ($query->execute() === FALSE) {
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
            $query->closeCursor();
        	throw new QueryLoadAddressException("Failed loading address by client; client's id = " . $id_client . $errInfo);
        }
        
        $addresses = array();
        while ($data = $query->fetch(PDO::FETCH_ASSOC)) $addresses[] = $data["tara"];        
        $query->closeCursor();
        return $addresses;    	
    }
    
    public static function queryLoadByClient($db, $id_client) {
    	
        $query = $db->prepare("SELECT * FROM `adresa`
                  				WHERE id_owner = :id_client
                    			AND tip = :CT_ADRESA_CLIENT
                  				LIMIT 1");
        
        $query->bindParam(':id_client', $id_client);
        $query->bindValue(':CT_ADRESA_CLIENT', CT_ADRESA_CLIENT);
                
        if ($query->execute() === FALSE) {
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
            $query->closeCursor();
        	throw new QueryLoadAddressException("Failed loading address by client; client's id = " . $id_client . $errInfo);
        }
            
        $data = $query->fetch(PDO::FETCH_ASSOC);
        
        if (!isset($data['id'])) {
        	$query->closeCursor();
        	throw new QueryLoadAddressException("Failed loading address by client; client's id = " . $id_client . " reason: id not existing");                    	
        }
        
        $adresa = new Address($data["tip"], $data["adresa"], $data["oras"], $data["judet"], $data["cod_postal"]
                                , $data["tara"], $data["nume_firma"], $data["tip_loc"]);
        $adresa->id_adresa = $data["id"];
        $adresa->id_owner = $data["id_owner"];
        $adresa->version = $data['version'];
        $adresa->impexp = $data['impexp'];
        $adresa->status = 0;
        $adresa->data = $data['data'];
        $adresa->data_efectiva = $data['data_efectiva'];
        $adresa->nume_contact = $data['nume_contact'];
        $adresa->tel_contact = $data['tel_contact'];
        $adresa->tip_marfa = $data['tip_marfa'];
        $adresa->nr_colete = $data['nr_colete'];
        $adresa->greutate = $data['greutate'];
        $adresa->alte_mentiuni = $data['alte_mentiuni'];
        $adresa->nume_birou_vamal = $data['nume_birou_vamal'];
        $adresa->cod_vama = $data['cod_vama'];
        $adresa->legatura_incarcare = $data['legatura_incarcare'];
        
        $query->closeCursor();
        return $adresa;
    }
    
    public static function queryLoadByFirma($db, $id_firma) {
    	
        $query = $db->prepare("SELECT * FROM `adresa`
                  				WHERE id_owner = :id_firma
                        		AND tip = :CT_ADRESA_FIRMA
                  				LIMIT 1");
        
        $query->bindParam(':id_firma', $id_firma);
        $query->bindValue(':CT_ADRESA_FIRMA', CT_ADRESA_FIRMA);                
             
        if ($query->execute() === FALSE) {        	
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
        	$query->closeCursor();
        	throw new QueryLoadAddressException("Failed loading address by firma; firma id = " . $id_firma . $errInfo);
        }
                        
        $data = $query->fetch(PDO::FETCH_ASSOC);
        
        $adresa = new Address($data["tip"], $data["adresa"], $data["oras"], $data["judet"], $data["cod_postal"]
                                , $data["tara"], $data["nume_firma"], $data["tip_loc"]);
                                
        $adresa->id_adresa = $data["id"];
        $adresa->id_owner = $id_firma;
        $adresa->version = $data['version'];
        $adresa->impexp = $data['impexp'];
        $adresa->data = $data['data'];
        $adresa->data_efectiva = $data['data_efectiva'];
        $adresa->nume_contact = $data['nume_contact'];
        $adresa->tel_contact = $data['tel_contact'];
        $adresa->tip_marfa = $data['tip_marfa'];
        $adresa->nr_colete = $data['nr_colete'];
        $adresa->greutate = $data['greutate'];
        $adresa->alte_mentiuni = $data['alte_mentiuni'];
        $adresa->nume_birou_vamal = $data['nume_birou_vamal'];
        $adresa->cod_vama = $data['cod_vama'];
        $adresa->legatura_incarcare = $data['legatura_incarcare'];
        
        $query->closeCursor();
//        var_dump($adresa);
        return $adresa;
    }
    
    public static function queryLoadByComandaForLocuri($db, $id_comanda, $tip_loc) {
    	
        $query = $db->prepare("SELECT * FROM `adresa`
                  				WHERE id_owner = :id_comanda
                        			AND tip = :CT_ADRESA_COMANDA
                        			AND tip_loc = :tip_loc 
                        		ORDER BY id");
        
        $query->bindParam(':id_comanda', $id_comanda);
        $query->bindValue(':CT_ADRESA_COMANDA', CT_ADRESA_COMANDA);
        $query->bindParam(':tip_loc', $tip_loc);
                
        if ($query->execute() === FALSE) {
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
            $query->closeCursor();
        	throw new QueryLoadAddressException("Failed loading address by comanda for locuri: client id = " . $id_client . " tip loc = " . $tip_loc . $errInfo);
        }
        
        $adrese = array();
        
        for ($i = 0; $i < $query->rowCount(); $i++) {
            $data = $query->fetch(PDO::FETCH_ASSOC);
            
            $adresa = new Address($data["tip"], $data["adresa"], $data["oras"], $data["judet"], $data["cod_postal"]
                                        , $data["tara"], $data["nume_firma"], $data["tip_loc"]);
            $adresa->id_adresa = $data["id"];
            $adresa->id_owner = (int) $data["id_owner"];
            $adresa->version = $data['version'];    
            $adresa->impexp = $data['impexp']; 
             
            $adresa->data = $data['data'];  
            $adresa->data_efectiva = $data['data_efectiva'];
            $adresa->nume_contact = $data['nume_contact'];
            $adresa->tel_contact = $data['tel_contact'];
            $adresa->tip_marfa = $data['tip_marfa'];
            $adresa->nr_colete = $data['nr_colete'];
            $adresa->greutate = $data['greutate'];
            $adresa->alte_mentiuni = $data['alte_mentiuni'];
            $adresa->nume_birou_vamal = $data['nume_birou_vamal'];
            $adresa->cod_vama = $data['cod_vama'];
            $adresa->legatura_incarcare = $data['legatura_incarcare'];
          
            $adresa->status = 0;
            $adrese[] = $adresa;
        }
        $query->closeCursor();                             
        return $adrese;
    }

    public static function deleteAddressByIdOwner($db, $id_owner, $tip) {
   	
    	$query = $db->prepare("DELETE FROM adresa 
    							WHERE id_owner = :id_owner AND tip = :tip");
    	
    	$query->bindParam(':id_owner', $id_owner);
    	$query->bindValue(':tip', CT_ADRESA_FIRMA);
    	    	
      	if ($query->execute() === FALSE) {      		
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
	  		$query->closeCursor();
    	  	throw new QueryDeleteAddressException("Failed deleting address with id_owner : " . $id_owner . $errInfo);
      	}
    	  	
      	$query->closeCursor();
      	return CT_RESULT_OK;
    }
    
    public static function getAdreseDescarcareForIncarcare($db, $idAdresaIncarcare) {
    	
    	$query = "SELECT legatura_incarcare FROM adresa WHERE id = $idAdresaIncarcare LIMIT 1";
										
		if (($result = $db->query($query)) === FALSE) {	
            $errInfo = $db->errorInfo();
            $errInfo = $errInfo[2];
           	throw new QueryLoadAddressException("Failed selecting legatura incarcare for address " . $idAdresaIncarcare);
		}
    	$data = $result->fetch(PDO::FETCH_ASSOC);
    	if (!empty($data)) {
			$id_adrese = explode(";", $data['legatura_incarcare']);
			
	        $adrese = array();
	        
	        for ($i = 0; $i < count($id_adrese); $i++) {
	            $adresa = Address::queryLoadAddress($db, $id_adrese[$i]);
	            $adrese[] = $adresa;
	        }                            
	        return $adrese;    	
	    		
    	}
    	else 
    		return false; 
    }
    
    public function queryUpdateAddressConfirmDate($db, $id_comanda, $id_adresa, $data_efectiva) {        
        $query = $db->prepare("UPDATE `adresa` SET
                                        `data_efectiva` = :data_efectiva,
                                        `version` = `version` + 1
                                WHERE tip = :tip    
                                AND id = :id
                                AND id_owner = :id_owner");

        $ct = CT_ADRESA_COMANDA;
        $query->bindParam(':data_efectiva', $data_efectiva);
        $query->bindParam(':tip', $ct);
        $query->bindParam(':id', $id_adresa);
        $query->bindParam(':id_owner', $id_comanda);

        if ($query->execute() === FALSE) {    
            $errInfo = $query->errorInfo();
            $errInfo = $errInfo[2];
              $query->closeCursor();
              throw new QueryUpdateAddressException("Failed updating address - owner's id: " . $this->id_owner . $errInfo);
        }
                           
        if ($query->rowCount() == 0) { 
            $query->closeCursor();
               throw new QueryUpdateAddressException("Failed updating address. Reason: wrong version!");
        }
        
        //close the cursor
        $query->closeCursor();
                
        return CT_RESULT_OK;
    }

}

?>